package yd.launcher.service;


import java.io.*;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.*;

public class Panel {
    private String name;
    private List<Action> actions;

    public Panel(String name, List<Action> actions) {
        this.name = name;
        this.actions = actions;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Action> getActions() {
        return actions;
    }

    public static List<Panel> fromProperties(Map<String, Object> props) {
        List<Panel> panels = new ArrayList<>();
        Field[] declaredFields = Action.class.getDeclaredFields();
        int panelSize = Integer.valueOf((String) props.get("panels"));
        for (int i = 0; i < panelSize; i++) {
            String panelName = (String) props.get("panels." + i + ".name");
            int actionSize = Integer.valueOf((String) props.get("panels." + i + ".actions"));
            List<Action> actions = new ArrayList<>(actionSize);
            panels.add(new Panel(panelName, actions));
            for (int j = 0; j < actionSize; j++) {
                Action action = new Action();
                actions.add(action);
                for (int k = 0; k < declaredFields.length; k++) {
                    try {
                        declaredFields[k].setAccessible(true);
                        String v = (String) props.get(String.format("panels.%s.actions.%s.%s", i, j, declaredFields[k].getName()));
                        if (declaredFields[k].getType() == int.class) {
                            declaredFields[k].setInt(action, Integer.valueOf(v));
                        } else if (declaredFields[k].getType() == boolean.class) {
                            declaredFields[k].setBoolean(action, Boolean.valueOf(v));
                        } else {
                            declaredFields[k].set(action, v);
                        }
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return panels;
    }

    public static Map<String, Object> toProperties(List<Panel> panels) {
        Field[] declaredFields = Action.class.getDeclaredFields();
        Map<String, Object> props =  new LinkedHashMap<>();
        props.put("panels", panels.size());
        for (int i = 0; i < panels.size(); i++) {
            props.put("panels." + i + ".name", panels.get(i).name);
            props.put("panels." + i + ".actions", panels.get(i).actions.size());
            List<Action> actions = panels.get(i).actions;
            for (int j = 0; j < actions.size(); j++) {
                for (int k = 0; k < declaredFields.length; k++) {
                    try {
                        declaredFields[k].setAccessible(true);
                        props.put(String.format("panels.%s.actions.%s.%s",i,j,declaredFields[k].getName()),
                                declaredFields[k].get(actions.get(j)));
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return props;
    }
}
